package com.monkey4flux.security.service;

import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

/**
 * @Description 用户信息查询与登录状态保存
 * @Author JL
 * @Date 2021/08/12
 * @Version V1.0
 */
@Service
public class UserService implements ReactiveUserDetailsService {

    private static final Map<String,UserDetails> userMap = new HashMap<>();

    /**
     * 获取指定用户信息与登录信息进行验证
     * @param username
     * @return
     */
    @Override
    public Mono<UserDetails> findByUsername(String username) {
        UserDetails userDetails = queryCacheUser(username);
        if (userDetails != null){
            return Mono.just(userDetails);
        }else {
            return Mono.just(queryDbUser(username));
        }
    }

    /**
     * 模拟查询redis缓存数据
     * @param username
     * @return
     */
    public UserDetails queryCacheUser(String username){
        return userMap.get(username);
    }

    /**
     * 模拟登录成功后保存redis缓存中
     * @param userDetails
     */
    public void saveCacheUser(UserDetails userDetails){
        userMap.put(userDetails.getUsername(), userDetails);
    }

    /**
     * 模拟查询数据库
     * @param username
     * @return
     */
    public UserDetails queryDbUser(String username){
        UserDetails userDetails = null;
        PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        if (username.equals("user")){
            userDetails = User.withUsername("user")
                    .password(encoder.encode("user"))
                    .roles("USER")
                    .build();
        }else if (username.equals("admin")) {
            userDetails = User.withUsername("admin")
                    .password(encoder.encode("admin"))
                    .roles("USER", "ADMIN")
                    .build();
        }else {
            throw new UsernameNotFoundException("无此账户");
        }
        System.out.println(userDetails.getPassword());
        return userDetails;
    }

}
